from flask import render_template, request, flash, redirect, url_for, abort
from app import login_required_with_check_scope
from app.admin import admin
from app.model.base import db
from app.model.order import Order
from app.model.product import Product
from app.validator.product import NewProductForm


@admin.route('/product/list', methods=['GET'])
@login_required_with_check_scope
def product_list_ep():
    """
        管理员查看商品列表路由

    :arg:
        p: 页码，可空，默认1
        k: 搜索关键字，可空

    :return:
        products: 商品列表
        pagination: 分页信息
    """
    page = request.args.get('p', 1, int)
    k = request.args.get('k', '', str)
    pagination = Product.query.filter(
        Product.name.like('%' + k + '%')
    ).order_by(
        Product.create_time.desc()
    ).paginate(page, per_page=10)

    products = pagination.items
    for i in range(len(products)):
        products[i].sales = Order.query.filter_by(product_id=products[i].id).count()
    return render_template('admin/product/list.html', products=products, pagination=pagination)


@admin.route('/product/new', methods=['GET', 'POST'])
@login_required_with_check_scope
def new_product_ep():
    """
        新建商品路由

    :form:
        img: 商品图片
        name: 商品名
        reserve: 库存
        price: 单价

    :return:
        if exception:
            form: 表单错误信息
        if success:
            重定向到商品列表页面
    """
    form = NewProductForm(request.form)
    if request.method == 'POST' and form.validate():
        product = Product()
        product.set_attrs(form.data)
        db.session.add(product)
        db.session.commit()
        return redirect(url_for('admin.product_list_ep'))
    flash(form.errors, 'form')
    return render_template('admin/product/new.html', form=form)


@admin.route('/product/edit/<product_id>', methods=['GET', 'POST'])
@login_required_with_check_scope
def edit_product_ep(product_id):
    """
        管理员编辑商品页面路由

    :param
        product_id: 商品id

    :return:
        form:
            用于jinja2渲染HTML表单的value。
            如果是POST，返回前台提交的form即可。
            如果是GET，返回查询到的Product实例。
    """
    product = Product.query.filter(Product.id == product_id).first()
    if not product:
        abort(404)

    form = NewProductForm(request.values)

    if request.method == 'POST' and form.validate():
        product.set_attrs(form.data)
        db.session.commit()
        return redirect(url_for('admin.product_list_ep'))

    flash(form.errors, 'form')
    ret_form = form if request.method == 'POST' else dict(data=product)
    return render_template('admin/product/edit.html', form=ret_form)


@admin.route('/product/invalid', methods=['POST'])
@login_required_with_check_scope
def invalid_product_ep():
    """
        下架商品

    :form:
        product_id: 商品id

    :return: 重定向到商品列表页面
    """
    product_id = request.form['product_id']
    product = Product.query.filter(Product.id == product_id).first()
    if not product:
        abort(404)
    with db.auto_commit():
        product.tog_invalid()
    return redirect(url_for('admin.product_list_ep'))


@admin.route('/product/valid', methods=['POST'])
@login_required_with_check_scope
def valid_product_ep():
    """
        上架已有商品

    :form:
        product_id: 商品id

    :return: 重定向到商品列表页面
    """
    product_id = request.form['product_id']
    product = Product.query.filter(Product.id == product_id).first()
    if not product:
        abort(404)
    with db.auto_commit():
        product.tog_valid()
    return redirect(request.referrer)
